package tsif.component.analyzer;

import java.util.concurrent.atomic.AtomicLong;

import tsif.component.log.Log;
import tsif.utils.ThreadUtils;
import tsif.utils.struct.result.Result;

/**
 * 分析器<br>
 * 对一段代码进行运行分析, 生成分析表.
 * 
 */
public class AnalyzeUtils {

	public static Result run(String name, final IUint uint, int total, final int oneCount, int thread) {
		if (total <= 0) {
			return Result.error("执行总数为0!");
		}
		thread = (total < thread) ? total : Math.max(thread, 1); // 最少1个线程.
		int batchCount = (int) Math.ceil(total / (double) thread); // 每个线程多少个
		// ExecutorService executorService = Executors.newFixedThreadPool(thread);
		// 运行计数器
		final AtomicLong running = new AtomicLong();
		final AtomicLong totalTime = new AtomicLong(); // 总用时
		final AtomicLong runCounter = new AtomicLong(); // 完成数量

		// 遍历创建线程
		for (int i = 0; i < thread; i++) {
			final int start = i * batchCount;
			final int size = Math.min(total - start, batchCount); // 计算这轮的数量

			// 提交线程
			running.incrementAndGet();
			ThreadUtils.run("t-" + i, new Runnable() {
				@Override
				public void run() {
					try {
						// 遍历循环
						long startTime = System.nanoTime();
						for (int i = 0; i < size; i++) {
							try {
								int index = start + i;
								// 执行
								uint.run(index, oneCount);
							} catch (Exception e) {
								Log.error("执行测试用例错误!", e);
							}
						}
						long endTime = System.nanoTime();
						// 计算时间(总时间)
						long dt = endTime - startTime;
						// 记录时间
						totalTime.addAndGet(dt);
						runCounter.addAndGet(size);
						return;
					} finally {
						running.decrementAndGet(); // 完成减少1
					}
				}
			});

		}

		// 等待处理结束.
		do {
			ThreadUtils.sleep(1000);
		} while (running.get() > 0);

		// 完成输出结果
		long totalCount = oneCount * Math.max(runCounter.get(), 1);
		long totalTime0 = totalTime.get();
		double avg = totalTime0 / ((double) totalCount);
		double s = totalTime0 * 0.000000001; // 转成秒
		int dps = (int) (totalCount / s);
		totalTime0 *= 0.000001; // 转成毫秒
		avg *= 0.000001; // 转成毫秒

		String info = name + " 结果: avg=" + avg + " totaltime=" + totalTime0 + " totalcount=" + totalCount + " dps=" + dps;
		return Result.create(Result.SUCCESS, info);
	}

	/** 测试用例接口 **/
	public interface IUint {
		/** 测试 **/
		void run(int index, int count);
	}

	/** 测试用例接口 **/
	public abstract class Uint implements IUint {
		public abstract void run(int index);
	}

	public static void main(String[] args0) throws Exception {

		Result result = run("test", new IUint() {
			@Override
			public void run(int index, int count) {
				// Log.debug("");
			}
		}, 99, 10, 10);
		Log.debug(result.getMsg());
	}
}
